#!/usr/bin/env python
# (C) 2000 Huaiyu Zhu <hzhu@users.sourceforge.net>.	 Licence: GPL
# $Id: interact.py,v 1.2 2000/09/14 09:48:10 hzhu Exp $
"""
interactive.py:  Interactive utilities for MatPy.
	Implements: help, demo, names, lookfor

Usage: python
from MatPy.interact import *

"""

import sys

class Interp:
	def __init__(self):
		self.__this__ = sys.modules[__name__]
		self.__objs__ = self.__this__.__dict__ 
		self._demos = []
		self._module = self.__this__
		print "\n   This is MatPy mode. Type help to get started\n"

	def names(self):
		print ", ".join(self.__objs__.keys())

	def help(self, x=None):
		"""
        names          to see list of current objects (functions, classes,...)
        help(name)     to get more information on <name> 
        lookfor(name)  to search docs for keyword <name>
        lookfor('')    to list docs for all names
        demo           to run the test examples

        quit, exit, CTRL-D to exit
		"""

		if x is None:
			print self.help.__doc__
		else:
			try: print x.__doc__
			except: print "No doc available for", `x`

	def demo(self, test=None):
		"demo : Run demos one by one"
		if test is None:
			tests = self._demos
		else:
			tests = [test]
		print "List of demos:", tests
		for test in tests:
			ans = raw_input("Run %s? " % test)
			if ans[:1] == 'N' or ans[:1] == 'n':
				break
			else:
				__import__("%s.%s" % (self._module, test))

	
	def lookfor(self, name=None):
		"lookfor(name) : Search docs for keyword <name>"
		if name is None:
			print self.lookfor.__doc__
			return
		else:
			try:
				name = string.split(name.__name__, '.')[-1]
			except:
				name = str(name)
		
		for fname, func in self.__objs__.items():
			if hasattr(func, "__doc__") and func.__doc__:
				doc = string.split(string.lstrip(func.__doc__), "\n")[0]
			else:
				doc = "%s: " % fname
			if string.find(string.lower(doc), string.lower(name)) != -1:
				print doc

#------------------------------------------------------------------
class FunctionWrapper:

	def __init__(self, func):
		self.func = func
		try: self.__doc__ = func.__doc__
		except: pass
		try: self.__name__ = func.__name__
		except: pass

	def __call__(self, *args, **kws):
		return apply(self.func, args, kws)
	
	def __repr__(self):
		self()
		return '         '

	def __str__(self):
		return self.__doc__
		
#------------------------------------------------------------------

if __name__ == "__main__":
	print __doc__

else:
	from MatPy import Matrix, efuncs, mfuncs, Stats, DynSys
	from MatPy.Matrix import *
	from MatPy.Scalar import *
	from MatPy.Tensor import *
	from MatPy.gplot import Gplot, wait
	from MatPy.efuncs import *
	from MatPy.mfuncs import *
	from MatPy.Stats import *
	from MatPy.DynSys import *
	import MatPy.tests

	interp = Interp()
	interp._demos = MatPy.tests.__all__
	interp._module = MatPy.tests.__name__
	
	help = FunctionWrapper(interp.help)
	names = FunctionWrapper(interp.names)
	demo = FunctionWrapper(interp.demo)
	lookfor = FunctionWrapper(interp.lookfor)
	quit = exit = FunctionWrapper(sys.exit)
	del FunctionWrapper
	
